/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fhc.view

import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.withSave
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.DialogProperties
import com.fhc.base.LocalManager
import kotlin.math.min
import kotlin.math.roundToInt


data class KeyLabel(var key: Any, var label: String, var selected: MutableState<Boolean> = mutableStateOf(false))


@Composable
fun StatusBarBox(offsetTop: Int = 26, bgColor:Color=colorScheme.primary){
    if(offsetTop > 0) {
        Box(
            modifier = Modifier.height(offsetTop.dp).fillMaxWidth().background(bgColor),
        )
    }
}

@Composable
fun BottomBarBox(offsetBottom: Int = 16,color: Color = colorScheme.primaryContainer) {
    if(offsetBottom > 0) {
        Box(
            modifier = Modifier.height(offsetBottom.dp).fillMaxWidth().background(color),
        )
    }
}


@Composable
fun FhcTopAppBar(@StringRes title: Int,  actions: @Composable (RowScope.() -> Unit) = {}, navigationIcon: @Composable (() -> Unit)? = null, onTopAppBarPositioned: ((LayoutCoordinates) -> Unit)? = null) {
    FhcTopAppBar(LocalManager.stringResource(title), actions= actions, navigationIcon = navigationIcon, onTopAppBarPositioned = onTopAppBarPositioned)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FhcTopAppBar(title: String,  actions: @Composable (RowScope.() -> Unit) = {}, navigationIcon: @Composable (() -> Unit)? = null, onTopAppBarPositioned: ((LayoutCoordinates) -> Unit)? = null) {
    val statusBarHeight = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()

    Column (modifier = Modifier.background(color = colorScheme.primary).onGloballyPositioned {
        if(onTopAppBarPositioned != null) onTopAppBarPositioned(it)
    },){
        StatusBarBox()
        TopAppBar(
            modifier = Modifier.fillMaxWidth(),
            title = { Text(text = title, style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.ExtraBold ) },
            navigationIcon = { navigationIcon?.invoke()  },
            colors = TopAppBarDefaults.topAppBarColors(
                containerColor = colorScheme.primary,
                titleContentColor = colorScheme.onPrimary,
                actionIconContentColor = colorScheme.onPrimary,
                navigationIconContentColor = colorScheme.onPrimary,
            ),
            actions =actions,
        )
    }
}


@Composable
fun FhcAlertDialog(
    modifier: Modifier = Modifier,
    onDismissRequest: () -> Unit,
    onConfirmation: () -> Unit,
    dialogTitle: String = "Tips",
    dialogText: String = "确定要执行此操作吗？",
    confirmText: String = "CONFIRM",
    cancelText: String = "CANCEL"
) {
    val dismissState = remember { MutableTransitionState(false) }
    dismissState.targetState = true

    AnimatedVisibility(
        visibleState = dismissState,
        enter = fadeIn() + expandVertically(),
        exit = fadeOut() + shrinkVertically()
    ) {
        AlertDialog(
            modifier = modifier
                .shadow(8.dp, shape = RoundedCornerShape(12.dp))
                .border(1.dp, colorScheme.outline, RoundedCornerShape(12.dp)),
            properties = DialogProperties(usePlatformDefaultWidth = false),
            onDismissRequest = onDismissRequest,
            title = {
                Text(
                    text = dialogTitle,
                    style = MaterialTheme.typography.titleMedium,
                    color = colorScheme.primary
                )
            },
            text = {
                Text(
                    text = dialogText,
                    style = MaterialTheme.typography.bodyLarge,
                    color = colorScheme.onSurfaceVariant
                )
            },
            confirmButton = {
                FilledTonalButton(
                    onClick = {
                        onConfirmation()
                        onDismissRequest()
                    },
                    shape = RoundedCornerShape(8.dp),
                    colors = ButtonDefaults.filledTonalButtonColors(
                        containerColor = colorScheme.primary,
                        contentColor = colorScheme.onPrimary
                    )
                ) {
                    Text(confirmText.uppercase())
                }
            },
            dismissButton = {
                FilledTonalButton(
                    onClick = onDismissRequest,
                    shape = RoundedCornerShape(8.dp),
                    colors = ButtonDefaults.filledTonalButtonColors(
                        containerColor = Color.LightGray
                    ),
//                    border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline)
                ) {
                    Text(cancelText.uppercase())
                }
            },
            shape = RoundedCornerShape(12.dp),
            containerColor = Color.White,
            tonalElevation = 6.dp
        )
    }
}

// 获取应用版本信息
@Composable
 fun FhcAppVersion(@StringRes text: Int) {
    val context = LocalContext.current
    val appVersion = context.packageManager.getPackageInfo(context.packageName, 0).versionName
    val appCode =  context.packageManager.getPackageInfo(context.packageName, 0).longVersionCode
    Box(modifier  = Modifier.fillMaxWidth()) {
        Text(
            modifier = Modifier.align(Alignment.Center).padding(bottom = 10.dp), // 设置文本居中对齐
            style = TextStyle(lineHeight = 14.sp, textAlign = TextAlign.Justify),
            maxLines = 3,
            textAlign = TextAlign.Center,
            text = stringResource(text) + "\nVersion:$appVersion",
            color = colorScheme.onPrimary.copy(alpha = 0.8f), // 文本颜色
            fontSize = 12.sp // 文本大小
        )
    }
}


@Preview
@Composable
fun CircleTextView(
    text: String ="ABCD",
    sizeDp: Dp = 48.dp,
    backgroundColor: Color = Color.Blue,
    textColor: Color = Color.White,
    colors: List<Color> = listOf(Color(0xFF409EFF), Color(0xFF13CE66), Color(0xFFFFBA00), Color(0xFFFB0D0D)  ),
    textStyle: TextStyle = MaterialTheme.typography.bodyMedium
) {
    val textMeasurer = rememberTextMeasurer()

    Canvas(
        modifier = Modifier.size(sizeDp).padding(4.dp)
    ) {
        // 绘制圆形背景
        drawCircle(color = backgroundColor)
        // 创建带颜色标注的文本
        val annotatedText = buildAnnotatedString {
            text.take(if(colors.isNotEmpty()) colors.size else min( 4, text.length ) ).forEachIndexed { index, char ->
                val color = colors.getOrElse(index) { Color.White }
                withStyle(style = SpanStyle(color = color)) {
                    append(char.toString())
                }
            }
        }
        // 计算最大文字尺寸
        val textLayoutResult = textMeasurer.measure(
            text = annotatedText,//AnnotatedString(text.take(4)),
            style = textStyle.copy( fontSize = 100.sp, color = textColor,fontFamily = FontFamily.Monospace,
                fontWeight = FontWeight.Bold)
        )


        // 计算缩放比例
        val diameter = sizeDp.toPx() - 8.dp.toPx() // 减去padding
        val textWidth = textLayoutResult.size.width
        val textHeight = textLayoutResult.size.height
        val scale = min( diameter / textWidth, diameter / textHeight ) * 0.80f // 保留20%边距

        // 绘制缩放后的文字
        drawIntoCanvas { canvas ->
            canvas.withSave {
                canvas.translate(center.x - (textWidth * scale) / 2, center.y - (textHeight * scale) / 2 )
                canvas.scale(scale, scale)
                drawText(
                    textLayoutResult = textLayoutResult,
                    topLeft = Offset.Zero
                )
            }
        }
    }
}


@Preview
@Composable
fun BoundedDraggableBox(initOffset: Offset = Offset.Zero,paddingValues: PaddingValues = PaddingValues(0.dp)) {
    val boxSize = 100.dp

    var offset by remember { mutableStateOf(initOffset) }
    val maxOffset = with(LocalDensity.current) {
        val screenWidth = LocalConfiguration.current.screenWidthDp.dp- paddingValues.calculateLeftPadding( LayoutDirection.Ltr) - paddingValues.calculateRightPadding(LayoutDirection.Ltr)
        val screenHeight = LocalConfiguration.current.screenHeightDp.dp - paddingValues.calculateTopPadding() - paddingValues.calculateBottomPadding()
        Offset(
            (screenWidth - boxSize).toPx(),
            (screenHeight - boxSize).toPx()
        )
    }

    Box(
        modifier = Modifier
            .fillMaxSize()
    ) {
        Box(
            modifier = Modifier
                .offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) }
                .size(boxSize)
                .background(Color.Green)
                .clip(RoundedCornerShape(8.dp))
                .pointerInput(Unit) {
                    detectDragGestures { _, dragAmount ->
                        offset = Offset(
                            x = (offset.x + dragAmount.x).coerceIn(0f, maxOffset.x),
                            y = (offset.y + dragAmount.y).coerceIn(0f, maxOffset.y)
                        )
                    }
                }
        )
    }

}
